package com.itcoon.cloud.framework.mybatis.core;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.itcoon.cloud.framework.page.IPageResult;
import com.itcoon.cloud.framework.page.ISortPage;

import java.io.Serializable;
import java.util.*;

public class Page<T> implements IPage<T>, IPageResult<T>, Iterable<T>, Serializable {

    private static final long serialVersionUID = 8545996863226528798L;
    protected List<T> records;
    protected long total;
    protected long size;
    protected long current;
    protected List<OrderItem> orders;

    public static <T>  Page<T> of(ISortPage sortPage){
        return new Page<>(sortPage.getSize(), sortPage.getCurrent(), sortPage.getAscProperties(), sortPage.getDescProperties());
    }

    public static <T> Page<T> empty(ISortPage page){
        Page<T> _page = new Page<>(page.getSize(), page.getCurrent(), new String[0], new String[0]);
        _page.setRecords(Collections.emptyList());
        _page.setTotal(0);
        return _page;
    }

    public static <T> Page<T> result(ISortPage page, List<T> records, long total){
        Page<T> _page = new Page<>(page.getSize(), page.getCurrent(), new String[0], new String[0]);
        _page.setRecords(records);
        _page.setTotal(total);
        return _page;
    }


    public static <T, R> Page<T> of(IPage<R> page, Collection<T> cols){
        Page<T> _page = new Page<>(page.getSize(), page.getCurrent(), new String[0], new String[0]);
        _page.setRecords(new ArrayList<>(cols));
        _page.setTotal(page.getTotal());
        _page.orders = page.orders();
        return _page;
    }

    private Page(long size, long current, String[] ascProperties,String[] descProperties ) {
        this.size = size == 0 ? Integer.MAX_VALUE : size;
        this.current = current;
        this.orders = OrderItem.ascs(ascProperties);
        orders.addAll(OrderItem.descs(descProperties));
    }

    public Page(){
        this.current = 1L;
        this.size = Integer.MAX_VALUE;
        this.orders = new ArrayList<>();
    }

    @Override
    public List<OrderItem> orders() {
        return this.orders;
    }

    @Override
    public List<T> getRecords() {
        return this.records;
    }

    @Override
    public IPage<T> setRecords(List<T> records) {
        this.records = records;
        return this;
    }

    @Override
    public long getTotal() {
        return this.total;
    }

    @Override
    public IPage<T> setTotal(long total) {
        this.total = total;
        return this;
    }

    @Override
    public long getSize() {
        return this.size;
    }

    @Override
    public IPage<T> setSize(long size) {
        this.size = size;
        return this;
    }

    @Override
    public long getCurrent() {
        return this.current;
    }

    @Override
    public IPage<T> setCurrent(long current) {
        this.current = current;
        return this;
    }

    @Override
    public Iterator<T> iterator() {
        return records.iterator();
    }

    @Override
    public String toString() {
        return "Page{" +
                "records=" + records +
                ", total=" + total +
                ", size=" + size +
                ", current=" + current +
                ", orders=" + orders +
                '}';
    }
}
